/**
 * 
 */
package cn.biplam.front.html.base;

import java.util.ArrayList;
import java.util.Iterator;

import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.front.html.base.Const.Window_Event;
import cn.biplam.front.htmlscript.HtmlScript;
import cn.biplam.front.htmlscript.script.ScriptBind;

/**
 * Html对象基础类
 * 		该接口类定义了全部Html对象所共有的属性和方法，
 * @author 	WangSong
 * @create 	2009-3-31 上午09:46:08
 * @version 1.0
 */
public abstract class Html {

	/**对象的内置容器 */
	private ArrayList<Html> aHtml;
	/**绑定脚本容器 */
	private ArrayList<String> binds;

	/**
	 * 构造方法 无参构造
	 */
	public Html(){
		this.aHtml=new ArrayList<Html>();
		this.binds=new ArrayList<String>();
	}

	/**
	 * 返回对象自身的客户端绑定脚本
	 * @return	对象自身的客户端绑定脚本
	 * @throws ErrorMessage
	 */
	private void _getBind(StringBuilder sb) throws ErrorMessage{
		for(String ite:this.binds){
			sb.append(ite);
		}
	}
	/**
	 * 返回实现类自定义的位于对象起始和结束标签内的 HTML
	 * @param sb				传入的字符串容器
	 * @throws ErrorMessage
	 */
	protected abstract void _getContent(StringBuilder sb) throws ErrorMessage;

	/**
	 * 设置客户端执行脚本命令
	 * @param script	脚本命令
	 * @throws ErrorMessage
	 */
	public void bind(String script) throws ErrorMessage{
		this.binds.add(script);
	}

	/**
	 * 设置客户端绑定的脚本命令(单独的Script声明段，支持多重绑定)
	 * @param sObjectID	绑定的对象ID
	 * @param event		绑定的事件ID
	 * @param script	绑定的脚本命令
	 * @throws ErrorMessage
	 */
	public void bind(String sObjectID,Window_Event event,String script) throws ErrorMessage{
		this.binds.add(new ScriptBind(sObjectID, event, script).draw());
	}

	/**
	 * 获取对象及其内容的 HTML 形式
	 * @return	对象及其内容的 HTML
	 * @throws ErrorMessage
	 */
	public String draw() throws ErrorMessage {
		StringBuilder sb = new StringBuilder();
		this.getHtml(sb);
		this.writeBind(sb);
		return sb.toString();
	}

	/**
	 * 返回对象的内置容器
	 * @return	对象的内置容器
	 */
	public ArrayList<Html> getAllElements(){
		return aHtml;
	}
	
	public void setAllElements(ArrayList<Html> htmls){
		this.aHtml=htmls;
	}

	/**
	 * 返回客户端绑定脚本的内容(用于异步通讯)
	 * @param sb	传入的写缓冲区	
	 * @throws ErrorMessage
	 */
	public void getBind(StringBuilder sb) throws ErrorMessage{
		Iterator<Html> ite = this.getAllElements().iterator();	
		this._getBind(sb);//后放入自己的绑定脚本
		while(ite.hasNext()){
			ite.next().getBind(sb);
		}
	}

	/**
	 * 返回绑定脚本集合
	 * @return	绑定脚本集合
	 */
	protected ArrayList<String> getBindset() {
		return binds;
	}

	/**
	 * 获取位于对象起始和结束标签内的 HTML
	 * @param sb	传入的写缓冲区	
	 * @return	对象起始和结束标签内的 HTML
	 * @throws ErrorMessage
	 */
	public String getContent(StringBuilder sb) throws ErrorMessage{
		this._getContent(sb);
		Iterator<Html> ite = this.getAllElements().iterator();
		while(ite.hasNext()){
			ite.next().getHtml(sb);
		}
		return sb.toString();
	}

	/**
	 * 获取对象及其内容的 HTML 形式(不包含客户端绑定脚本)
	 * @param sb	传入的写缓冲区	
	 * @throws ErrorMessage
	 */
	public abstract void getHtml(StringBuilder sb) throws ErrorMessage;

	/**
	 * 存入一个Html对象到内置容器
	 * @param html	Html对象实例
	 * @throws ErrorMessage 
	 */
	public void put(Html html) throws ErrorMessage{
		this.aHtml.add(html);
	}

	/**
	 * 放入html容器
	 * @param htmls	Html对象集合
	 * @throws ErrorMessage
	 */
	protected void putAllElements(ArrayList<Html> htmls) throws ErrorMessage {
		for(Html ite:htmls){
			this.put(ite);
		}
	}

	/**
	 * 放入绑定脚本容器
	 * @param binds	脚本集合
	 * @throws ErrorMessage
	 */
	protected void putAllBinds(ArrayList<String> binds) throws ErrorMessage {
		for(String ite:binds){
			this.bind(ite);
		}
	}

	/**
	 * 返回Html表示的文本(同draw,但屏蔽异常)
	 * @return	Html表示的文本
	 */
	public String toString(){
		try {
			return this.draw();
		} catch (ErrorMessage e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 写客户端绑定脚本(由实现类调用)
	 * @param sb	传入的写缓冲区	
	 * @throws ErrorMessage
	 */
	protected void writeBind(StringBuilder sb) throws ErrorMessage{
		StringBuilder sbTemp=new StringBuilder();
		this.getBind(sbTemp);
		if(sbTemp.length()>0){
			HtmlScript script=new HtmlScript(sbTemp.toString());
			sb.append(script.draw());
		}
	}
	
	/**
	 * 获取Html对象元素
	 * @param i 元素下标
	 * @return
	 */
	public Html get(int i){
		return this.aHtml.get(i);
	}
}
